import wbi from './wbi'
import * as _ from 'lodash-es'
import axios from 'axios'
import router from '@renderer/router'
import { useUserStore } from '@renderer/stores/user'

import type { AxiosRequestConfig, AxiosResponse } from 'axios'

type ApiResponse<T = any> = {
  code: number
  data?: T
  message: string
  ttl: number
}

const headers = {}

const instance = axios.create()

// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  function (response: AxiosResponse<ApiResponse>) {
    const {
      data: { code, message }
    } = response
    // 未登录
    if (code === -101) {
      router.push({ name: 'login' })
      useUserStore().setIsLogin(false)
      throw new Error(message)
    }
    return response
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error)
  }
)

async function request<T = any>(config: AxiosRequestConfig) {
  if (config.method === 'get' && Object.keys(config.data).length) {
    const params = await wbi(config.data)
    delete config.data
    config.url += '?' + params
  }
  const response = await instance.request<ApiResponse<T>>(config)
  return response.data
}

export const apiPlayurl = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/player/wbi/playurl',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 导航栏用户信息
export const apiNav = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/web-interface/nav',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

export const apiSearchType = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/web-interface/wbi/search/type',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 查询视频分P列表 (avid/bvid转cid)
export const apiPlayerPagelist = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/player/pagelist',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 查询私有笔记内容
export const apiNoteInfo = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/note/info',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 保存视频笔记
export const apiNoteAdd = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/note/add',
        method: 'post',
        data,
        headers
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      },
      config
    )
  )
}

// 获取我的信息
export const apiAccount = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/member/web/account',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 上报视频播放心跳（web端）
export const apiHeartbeat = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/click-interface/web/heartbeat',
        method: 'post',
        data,
        headers
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      },
      config
    )
  )
}

// 申请二维码
export const apiQrcodeGenerate = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 扫码登录
export const apiQrcodePoll = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://passport.bilibili.com/x/passport-login/web/qrcode/poll',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 退出登录
export const apiLoginExit = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://passport.bilibili.com/login/exit/v2',
        method: 'post',
        data,
        headers
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      },
      config
    )
  )
}

export interface ApiDraftAddupdateParams {
  csrf: string
  title: string
  content: string
  aid?: number
}

// 专栏投稿草稿箱新增、编辑
// 编辑需要带上 aid
export const apiDraftAddupdate = (data: ApiDraftAddupdateParams, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/article/creative/draft/addupdate',
        method: 'post',
        data,
        headers
      },
      {
        data: {
          // 标记为新版编辑器
          type: 3,
          // 专栏分类：音乐舞蹈
          category: 39,
          // 封面地址
          image_urls: 'http://i0.hdslb.com/bfs/article/39c86f20bce4a03321db095e6d989a5619074019.jpg'
        }
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      },
      config
    )
  )
}

// 专栏投稿草稿箱列表
export const apiDraftList = (data = {}, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://member.bilibili.com/x/web/draft/list',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 专栏投稿草稿箱查看内容
export const apiDraftView = (data: { aid: number }, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/article/creative/draft/view',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 专栏投稿草稿箱删除
export const apiDraftDelete = (data: { aid: number; csrf: string }, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://member.bilibili.com/x/web/draft/delete',
        method: 'post',
        data,
        headers
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      },
      config
    )
  )
}

export interface ApiArcSearchParams {
  mid: number
  order?: 'pubdate' | 'click' | 'stow'
  tid?: number
}

// 查询用户投稿视频明细
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/user/space.md#:~:text=https://api.bilibili.com/x/space/wbi/arc/search
export const apiArcSearch = (data: ApiArcSearchParams, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/space/wbi/arc/search',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 查询用户信息
export const apiArcInfo = (
  data: {
    mid: number
    w_webid: string
  },
  config = {}
) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/space/wbi/acc/info',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 获取用户合集
export const apiSeasonsSeriesList = (
  data: {
    mid: number
    w_webid: string
    page_num: number
    page_size: number
  },
  config = {}
) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/polymer/web-space/seasons_series_list',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 获赞数、播放数
export const apiSpaceUpstat = (data: { mid: number }, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/space/upstat',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 获取用户空间合集内的视频
export const apiSeasonsArchivesList = (
  data: {
    mid: number
    season_id: number
    page_num: number
    page_size: number
  },
  config = {}
) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/polymer/web-space/seasons_archives_list',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 获取视频详细信息(web端)
export const apiInterfaceView = (data: { bvid: string }, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/web-interface/wbi/view',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 获取视频超详细信息(web端)
export const apiInterfaceViewDetail = (data: { bvid: string }, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/web-interface/wbi/view/detail',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}

// 获取指定系列视频
export const apiSeriesArchives = (data: { mid: number; series_id: number }, config = {}) => {
  return request(
    _.merge(
      {
        url: 'https://api.bilibili.com/x/series/archives',
        method: 'get',
        data,
        headers
      },
      config
    )
  )
}
